package com.hulk.ratel.web.initializer;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.hulk.common.util.SpringContextHolder;
import com.hulk.ratel.config.properties.RatelProperties;
import com.hulk.ratel.web.interceptor.SecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.config.annotation.*;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 作者 hulk
 * @version 创建时间：2016年7月6日 下午4:50:19 类说明
 */



@Configuration
//@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {


	@Autowired
	private RatelProperties ratelProperties;

	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setBasename("classpath:messages");
		messageSource.setCacheSeconds(3600);
		messageSource.setUseCodeAsDefaultMessage(true);
		messageSource.setDefaultEncoding("UTF-8");
		return messageSource;
	}

	@Bean
	public FilterRegistrationBean hiddenHttpMethodFilterRegistration() {
	    FilterRegistrationBean registration = new FilterRegistrationBean();
	    registration.setFilter(new HiddenHttpMethodFilter());
	    registration.setName("hiddenHttpMethodFilter");
	    registration.addUrlPatterns("/*");
	    //registration.addServletNames("dispatcherServlet");
	    registration.setOrder(3);
	    return registration;
	}

	@Bean
	public Executor eventBusAsync() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(3);
		executor.setMaxPoolSize(10);
		executor.setQueueCapacity(5);
		executor.setThreadNamePrefix("eventBusAsync-");

		// rejection-policy：当pool已经达到max size的时候，如何处理新任务
		// CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执行
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}

	@Bean(name={"eventBus"})
	public EventBus eventBus(Executor eventBusAsync) {
		return new AsyncEventBus(eventBusAsync);
	}


	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
		if (ratelProperties.getSwaggerOpen()) {
			registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
			registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
		}
		super.addResourceHandlers(registry);
	}

	@Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //配置跳转
       // registry.addViewController("/nav").setViewName("forward:/static/nav.html");
    }


	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.setUseSuffixPatternMatch(false);
	}

	@Bean
	public SpringContextHolder SpringContextHolder() {
		return new SpringContextHolder();
	}
	@Bean
	public SecurityInterceptor securitsyInterceptor(){
		return new SecurityInterceptor();
	}
//	@Bean
//	public RateLimitInterceptor rateLimitInterceptor(){
//		return new RateLimitInterceptor();
//	}
//

	@Override
	public void addInterceptors(InterceptorRegistry registry ) {

		registry.addInterceptor(securitsyInterceptor()).addPathPatterns("/**").excludePathPatterns("/rest/heartbeat").excludePathPatterns("/favicon.ico");

	}

/*	@Bean
	public ServletListenerRegistrationBean<ContextLoaderListener> servletListenerRegistrationBean() {
		return new ServletListenerRegistrationBean<ContextLoaderListener>(new ContextLoaderListener());
	}*/

	/*@Bean
	public TemplateResolver templateResolver() {

		TemplateResolver templateResolver = new ServletContextTemplateResolver();
		templateResolver.setPrefix("/WEB-INF/templates");
		templateResolver.setSuffix(".html");
		templateResolver.setTemplateMode("HTML5");
		return templateResolver;
	}

	@Bean
	public SpringTemplateEngine springTemplateEngine() {

		SpringTemplateEngine templateEngine = new SpringTemplateEngine();
		templateEngine.setTemplateResolver(templateResolver());
		return templateEngine;
	}

	@Bean
	public ThymeleafViewResolver thymeleafViewResolver() {

		ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
		thymeleafViewResolver.setTemplateEngine(springTemplateEngine());
		thymeleafViewResolver.setViewClass(ThymeleafView.class);
		return thymeleafViewResolver;

	}
	 */


//	@Bean(name={"hiddenHttpMethodFilter"})
//	public Filter hiddenHttpMethodFilter() {
//		HiddenHttpMethodFilter  hiddenHttpMethodFilter	= new HiddenHttpMethodFilter();
//		return  hiddenHttpMethodFilter;
//	}


//	@Bean(name={"characterEncodingFilter"})
//    public Filter characterEncodingFilter() {
//        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
//        characterEncodingFilter.setEncoding("UTF-8");
//        characterEncodingFilter.setForceEncoding(true);
//        return characterEncodingFilter;
//    }


	/*
    @Bean
	public ObjectMapper nonNullObjectMapper() {
		ObjectMapper objectMapper = new ObjectMapper();
		objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		return objectMapper;
	}*/
//	DispatcherServlet


	/*	@Bean(name="contentNegotiationManagerFactoryBean")
	  public ContentNegotiationManagerFactoryBean contentNegotiationManagerFactoryBean(){
		ContentNegotiationManagerFactoryBean factoryBean = new ContentNegotiationManagerFactoryBean ();
		factoryBean.setDefaultContentType(MediaType.APPLICATION_JSON);
		Map<String, MediaType> mediaTypes = new HashMap<String, MediaType>();
		mediaTypes.put("json", MediaType.APPLICATION_JSON);
		factoryBean.addMediaTypes(mediaTypes);
	    return factoryBean;
	  }*/


	//defaultContentType
	/*@Bean
	public FilterRegistrationBean characterEncodingFilterRegistration() {
		CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
		characterEncodingFilter.setEncoding("UTF-8");
		characterEncodingFilter.setForceEncoding(true);
		FilterRegistrationBean registration = new FilterRegistrationBean();
		registration.setFilter(characterEncodingFilter);
		registration.setName("characterEncodingFilter");
		registration.addUrlPatterns("/*");
		// registration.addServletNames("dispatcherServlet");
		registration.setOrder(3);
		return registration;
	}*/


}
